home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / GRAPHICS / DASHANIM.ZIP / PLAYDSH.ZIP / XMM.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-12  |  14.9 KB  |  549 lines

  1. //XMM.CPP
  2.  
  3. #include <iostream.h>
  4. #include <fstream.h>
  5. #include <dos.h>
  6. #include <dir.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include "xmm.h"
  10.  
  11. void DashXMM::detect(void){
  12.   REGS inregs;
  13.   REGS outregs;
  14.   inregs.x.ax = 0x4300;
  15.   int86(XMSINT, &inregs, &outregs);
  16.   int comparing = outregs.h.al;
  17.   detected = FALSE;
  18.   if (comparing == 0x80) detected = TRUE;
  19. }
  20.  
  21.  
  22. XMSerror DashXMM::initialize(void){
  23.   initialized = FALSE;
  24.   if (detected){
  25.     REGS inregs;
  26.     REGS outregs;
  27.     SREGS segregs;
  28.     inregs.x.ax = 0x4310;
  29.     int86x(XMSINT, &inregs, &outregs, &segregs);
  30.     dword bx, es;
  31.     bx = outregs.x.bx;
  32.     es = segregs.es;
  33.     CONTROL = (void far(*)())(MK_FP(es, bx));
  34.     initialized = TRUE;
  35.     get_versions();
  36.     return OK;
  37.   }
  38.   if (!detected){
  39.     if (request_swapfile){
  40.       initialized = TRUE;
  41.       using_swapfile = TRUE;
  42.       return OK;
  43.     }
  44.   }
  45.   initialized = FALSE;
  46.   return XMS_NOT_INITIALIZED;
  47. }
  48.  
  49. void DashXMM::get_versions(void){
  50.   if (detected){
  51.     if (initialized){
  52.       XMS_version = 0;
  53.       driver_version = 0;
  54.       if(!using_swapfile){
  55.     _AH = XMS_const::GET_VERSION_NUMBER;
  56.     CONTROL();
  57.     XMS_version = _AX;
  58.     driver_version = _BX;
  59.       }
  60.     }
  61.   }
  62. }
  63.  
  64. XMSerror DashXMM::query_free_XMS(XMSfree& freemem){
  65.   if (detected){
  66.     if (initialized){
  67.       if (!using_swapfile){
  68.     _AH = XMS_const::QUERY_FREE_XMS;
  69.     CONTROL();
  70.     if (_AX == FAILURE){
  71.       if (verbose) display_error(XMSerror(_BL));
  72.       return XMSerror(_BL);
  73.     }
  74.     freemem.largest = dword(_AX * 1024L);
  75.     _AH = XMS_const::QUERY_FREE_XMS;
  76.     CONTROL();
  77.     if (_AX == FAILURE){
  78.       if (verbose) display_error(XMSerror(_BL));
  79.       return XMSerror(_BL);
  80.     }
  81.     freemem.total   = dword(_DX * 1024L);
  82.     return OK;
  83.       }
  84.     }
  85.   }
  86.   return XMS_NOT_INITIALIZED;
  87. }
  88.  
  89. XMSerror DashXMM::allocate(dword bytes){
  90.   if ((detected) || (using_swapfile == TRUE)){
  91.     if (initialized){
  92.       boolean need_swapfile = using_swapfile;
  93.       const long KB = 1024;
  94.       int KB_requested = 0;
  95.       int byte_overflow = 0;
  96.       dword bytes_granted = 0;
  97.       byte_overflow = bytes % KB;
  98.       KB_requested = int(bytes / KB);
  99.       if (byte_overflow > 0) KB_requested++;
  100.       bytes_granted = long(KB_requested) * KB;
  101.       if (!using_swapfile){
  102.     XMS_handle = 0;
  103.     _DX = KB_requested;
  104.     _AH = XMS_const::ALLOCATE_XMS;
  105.     CONTROL();
  106.     if (_AX) XMS_handle = _DX;
  107.     if (int(_AX) == FAILURE){
  108.       if (verbose) display_error(XMSerror(_BL));
  109.       if (request_swapfile) need_swapfile = TRUE;
  110.       if (!request_swapfile) return(XMSerror(_BL));
  111.     }
  112.     if (!need_swapfile){
  113.       bytes_allocated = bytes_granted;
  114.       using_swapfile = FALSE;
  115.       if (verbose){
  116.         cout << "\nRequested XMS Block of " << bytes << " bytes.\n";
  117.         cout << "\nGranted block, in XMS, of " << bytes_allocated << " bytes.\n";
  118.         cout << "\nSwapfile was not necessary.\n";
  119.       }
  120.       return OK;
  121.     }
  122.       }
  123.       if (need_swapfile){
  124.     XMSerror error = create_SF(KB_requested);
  125.     if (error == FAILURE){
  126.       if (verbose) display_error(XMSerror(_BL));
  127.       return XMSerror(error);
  128.     }
  129.     if (verbose){
  130.       cout << "Requested XMS Block of " << bytes << " bytes.\n";
  131.       cout << "Granted block of SWAPFILE of " << bytes_allocated << " bytes.\n";
  132.       cout << "Swapfile needed to be created to allocate this memory.\n";
  133.     }
  134.     return OK;
  135.       }
  136.     }
  137.   }
  138.   if (verbose){
  139.     cout << "\nError:  XMS was either not detected or not initialized.\n";
  140.   }
  141.   return XMS_NOT_INITIALIZED;
  142. }
  143.  
  144. XMSerror DashXMM::free(void){
  145.   if (bytes_allocated == 0){
  146.     XMSerror error = FAILURE;
  147.     if (verbose) display_error(error);
  148.     return error;
  149.   }
  150.   if ((detected) || (using_swapfile == TRUE)){
  151.     if (initialized){
  152.       if (!using_swapfile){
  153.     _DX = XMS_handle;
  154.     _AH = XMS_const::FREE_XMS;
  155.     CONTROL();
  156.     if (int(_AX) == FAILURE){
  157.       if (verbose) display_error(XMSerror(_BL));
  158.       return XMSerror(_BL);
  159.     }
  160.     return OK;
  161.       }
  162.       if (using_swapfile){
  163.     delete_SF();
  164.     return OK;
  165.       }
  166.     }
  167.   }
  168.   if (verbose){
  169.     cout << "\nError:  XMS was either not detected or not initialized.\n";
  170.   }
  171.   return XMS_NOT_INITIALIZED;
  172. }
  173.  
  174. //the move function is overloaded...handles 3 kinds of move:
  175. //1) XMS->XMS
  176. //2) CONVENTIONAL->XMS
  177. //3) XMS->CONVENTIONAL
  178.  
  179. //they're fast...very fast
  180.  
  181. XMSerror DashXMM::move(dword bytes, void far* address_to, dword offset_from){
  182.   //creates move struct conventional->XMS
  183.   if ((int(bytes % 2)) > 0) bytes++;  //length must be even
  184.   EMMstruct.length      = bytes;
  185.   EMMstruct.src_handl   = XMS_handle;
  186.   EMMstruct.src_offset  = dword(offset_from);
  187.   EMMstruct.dest_handl  = 0;
  188.   EMMstruct.dest_offset = dword(address_to);
  189.   word movestruct = FP_OFF(&EMMstruct);
  190.  
  191.   if ((detected) || (using_swapfile == TRUE)){
  192.     if (detected){
  193.       if (initialized){
  194.         _SI = movestruct;
  195.         _AH = XMS_const::MOVE_XMS;
  196.         CONTROL();
  197.         if (_AX == FAILURE){
  198.           if (verbose) display_error(XMSerror(_BL));
  199.           return XMSerror(_BL);
  200.         }
  201.         return OK;
  202.       }
  203.     }
  204.     if (using_swapfile){
  205.       SF_move(bytes, address_to, offset_from);
  206.       return OK;
  207.     }
  208.   }
  209.   if (verbose){
  210.     cout << "\nError:  XMS was either not detected or not initialized.\n";
  211.   }
  212.   return XMS_NOT_INITIALIZED;
  213. }
  214.  
  215. XMSerror DashXMM::move(dword bytes, dword offset_to, dword offset_from){
  216.   //creates move struct conventional->XMS
  217.   if ((int(bytes % 2)) > 0) bytes++;  //length must be even
  218.   EMMstruct.length      = bytes;
  219.   EMMstruct.src_handl   = XMS_handle;
  220.   EMMstruct.src_offset  = dword(offset_from);
  221.   EMMstruct.dest_handl  = XMS_handle;
  222.   EMMstruct.dest_offset = dword(offset_to);
  223.   word movestruct = FP_OFF(&EMMstruct);
  224.  
  225.   if ((detected) || (using_swapfile == TRUE)){
  226.     if (detected){
  227.       if (initialized){
  228.         _SI = movestruct;
  229.         _AH = XMS_const::MOVE_XMS;
  230.         CONTROL();
  231.         if (_AX == FAILURE){
  232.           if (verbose) display_error(XMSerror(_BL));
  233.           return XMSerror(_BL);
  234.         }
  235.         return OK;
  236.       }
  237.     }
  238.     if (using_swapfile){
  239.       SF_move(bytes, offset_to, offset_from);
  240.       return OK;
  241.     }
  242.   }
  243.   if (verbose){
  244.     cout << "\nError:  XMS was either not detected or not initialized.\n";
  245.   }
  246.   return XMS_NOT_INITIALIZED;
  247. }
  248.  
  249.  
  250.  
  251. XMSerror DashXMM::move(dword bytes, dword offset_to, void far* address_from){
  252.   //creates move struct conventional->XMS
  253.   if ((int(bytes % 2)) > 0) bytes++;  //length must be even
  254.   EMMstruct.length      = bytes;
  255.   EMMstruct.src_handl   = 0;
  256.   EMMstruct.src_offset  = dword(address_from);
  257.   EMMstruct.dest_handl  = XMS_handle;
  258.   EMMstruct.dest_offset = dword(offset_to);
  259.   word movestruct = FP_OFF(&EMMstruct);
  260.  
  261.   if ((detected) || (using_swapfile == TRUE)){
  262.     if (detected){
  263.       if (initialized){
  264.         _SI = movestruct;
  265.         _AH = XMS_const::MOVE_XMS;
  266.         CONTROL();
  267.         if (_AX == FAILURE){
  268.           if (verbose) display_error(XMSerror(_BL));
  269.           return XMSerror(_BL);
  270.         }
  271.         return OK;
  272.       }
  273.     }
  274.     if (using_swapfile){
  275.       SF_move(bytes, offset_to, address_from);
  276.       return OK;
  277.     }
  278.   }
  279.   if (verbose){
  280.     cout << "\nError:  XMS was either not detected or not initialized.\n";
  281.   }
  282.   return XMS_NOT_INITIALIZED;
  283. }
  284.  
  285. #pragma warn -par
  286.  
  287. XMSerror DashXMM::lock(void far* ptr){
  288.   if (detected){
  289.     if (initialized){
  290.       _DX = XMS_handle;
  291.       _AH = XMS_const::LOCK_XMS;
  292.       CONTROL();
  293.       ptr = MK_FP(_DX, _BX);
  294.       if (_AX == FAILURE){
  295.     if (verbose) display_error(XMSerror(_BL));
  296.     return XMSerror(_BL);
  297.       }
  298.       return OK;
  299.     }
  300.   }
  301.   if (verbose){
  302.     cout << "\nError:  XMS was either not detected or not initialized.\n";
  303.   }
  304.   return XMS_NOT_INITIALIZED;
  305. }
  306.  
  307. #pragma warn +par
  308.  
  309. XMSerror DashXMM::unlock(void){
  310.   if (detected){
  311.     if (initialized){
  312.       _DX = XMS_handle;
  313.       _AH = XMS_const::UNLOCK_XMS;
  314.       CONTROL();
  315.       if (_AX == FAILURE){
  316.     if (verbose) display_error(XMSerror(_BL));
  317.     return XMSerror(_BL);
  318.       }
  319.       return OK;
  320.     }
  321.   }
  322.   if (verbose){
  323.     cout << "\nError:  XMS was either not detected or not initialized.\n";
  324.   }
  325.   return XMS_NOT_INITIALIZED;
  326. }
  327.  
  328.  
  329.  
  330. void DashXMM::display_error(XMSerror error){
  331.   char s[80];
  332.   if (verbose){
  333.     cout << "DashXMM:  Error reported by XMS driver:\n";
  334.     cout << "Error #: " << int(error) << "\n";
  335.     switch(error){
  336.       case FAILURE:                  cout << "Failed operation.";
  337.     break;
  338.       case OK:                       cout << "Reports OK";
  339.     break;
  340.       case XMS_NOT_INITIALIZED:      cout << "XMS is not initialized.";
  341.     break;
  342.       case NOT_ENOUGH_XMS:           cout << "Not enough XMS.";
  343.     break;
  344.       case FUNCTION_NOT_IMPLEMENTED: cout << "Function not implemented.";
  345.     break;
  346.       case VDISK_DETECTED:           cout << "VDisk was detected.";
  347.     break;
  348.       case A20_ERROR:                cout << "A20 line error";
  349.     break;
  350.       case GENERAL_ERROR:            cout << "General Driver error";
  351.     break;
  352.       case UNRECOVERABLE_ERROR:      cout << "Unrecoverable driver error.";
  353.     break;
  354.       case HMA_DOES_NOT_EXIST:       cout << "HMA doesn't exist.";
  355.     break;
  356.       case HMA_IN_USE:               cout << "HMA is already in use.";
  357.     break;
  358.       case DX_LESS_THAN_HMAMIN:      cout << "DX < /HMAMIN parameter";
  359.     break;
  360.       case HMA_NOT_ALLOCATED:        cout << "HMA not allocated.";
  361.     break;
  362.       case A20_STILL_ENABLED:        cout << "A20 line still enabled.";
  363.     break;
  364.       case NO_MORE_MEMORY:           cout << "No more XMS available.";
  365.     break;
  366.       case NO_MORE_HANDLES:          cout << "All handles have been used up.";
  367.     break;
  368.       case INVALID_HANDLE:           cout << "Invalid handle specified.";
  369.     break;
  370.       case SOURCE_HANDLE_INVALID:    cout << "Source handle is invalid.";
  371.     break;
  372.       case SOURCE_OFFSET_INVALID:    cout << "Source offset is invalid.";
  373.     break;
  374.       case DEST_HANDLE_INVALID:      cout << "Destination handle is invalid.";
  375.     break;
  376.       case DEST_OFFSET_INVALID:      cout << "Destination offset is invalid.";
  377.     break;
  378.       case LENGTH_INVALID:           cout << "Length specified is invalid.";
  379.     break;
  380.       case INVALID_OVERLAP:          cout << "Invalid overlap requested.";
  381.     break;
  382.       case PARITY_ERROR:             cout << "Parity error.";
  383.     break;
  384.       case BLOCK_NOT_LOCKED:         cout << "Block is not locked.";
  385.     break;
  386.       case BLOCK_LOCKED:             cout << "Block is locked.";
  387.     break;
  388.       case BLOCK_LOCK_COUNT_OVERFLOW: cout << "Block lock count overflow.";
  389.     break;
  390.       case LOCK_FAILED:              cout << "Locking failed.";
  391.     break;
  392.       case SMALLER_UMB_AVAIL:        cout << "Only a smaller UMB is available.";
  393.     break;
  394.       case NO_UMB_AVAIL:             cout << "No UMB is available.";
  395.     break;
  396.       case UMB_SEGMENT_NUMBER_INVALID: cout << "UMB segment num. invalid.";
  397.     break;
  398.       default:                       cout << "Undefined Error";
  399.     }
  400.     cout << "\n";
  401.   }
  402. }
  403.  
  404.  
  405. XMSerror DashXMM::query_free_SF(XMSfree& freemem){
  406.    struct dfree free;
  407.    long avail;
  408.    int drive = SF_drive;
  409.  
  410.    drive = getdisk();
  411.    getdfree(drive+1, &free);
  412.    if (free.df_sclus == 0xFFFF)
  413.    {
  414.       if (verbose) cout<<("Error in getdfree() call\n");
  415.       return FAILURE;
  416.    }
  417.  
  418.    avail =  (long) free.df_avail
  419.         * (long) free.df_bsec
  420.         * (long) free.df_sclus;
  421.    freemem.total = avail;
  422.    freemem.largest = avail;
  423.    return OK;
  424. }
  425.  
  426. XMSerror DashXMM::create_SF(dword Kbytes){
  427.   //first, check to make sure there's enough space
  428.   XMSfree freedisk;
  429.   XMSerror error = query_free_SF(freedisk);
  430.   if (error == FAILURE){
  431.     if (verbose) display_error(XMSerror(error));
  432.     return XMSerror(error);
  433.   }
  434.   if (freedisk.largest < dword(Kbytes * 1024)){
  435.     error = NOT_ENOUGH_XMS;
  436.     if (verbose) display_error(XMSerror(error));
  437.     return XMSerror(error);
  438.   }
  439.  
  440.   //now that we are relatively sure that we'll be able to handle this,
  441.   //let's open the file.
  442.   swapfile.open(swapfile_name, ios::out);
  443.   if (!swapfile.good()){
  444.     if(verbose) cout << "\nError opening file " << swapfile_name << "\n\n";
  445.     return FAILURE;
  446.   }
  447.   //writes blank pages so that we can seekp() whereever we want.
  448.   for (int i = 0; i < (Kbytes); i++){
  449.     for (int j = 0; j < 1024UL; j++) swapfile.put(0);
  450.   }
  451.   //we now have a blank file, it needs to be closed and opened for ios::ate
  452.   //to be read, however.
  453.   swapfile.close();
  454.   swapfile.open(swapfile_name, ios::in | ios::out | ios::ate);
  455.   //now that that's handled, the other routines do the rest!
  456.   bytes_allocated = dword(Kbytes * 1024UL);
  457.   using_swapfile = TRUE;
  458.   return OK;
  459. }
  460.  
  461. void DashXMM::delete_SF(void){
  462.   swapfile.close();
  463.   unlink(swapfile_name);
  464. }
  465.  
  466. XMSerror DashXMM::SF_move(dword bytes, dword offset_to, void far* address_from){
  467.   char far* byte_from_pointer = (char far*)(address_from);
  468.   dword i;
  469.   for (i = 0; i < bytes; i++){
  470.     swapfile.seekp(offset_to+i);
  471.     swapfile.put(byte_from_pointer[i]);
  472.   }
  473.   if (verbose) cout << "Swapfile move completed.\n";
  474.   return OK;
  475. }
  476.  
  477. XMSerror DashXMM::SF_move(dword bytes, void far* address_to, dword offset_from){
  478.   char far* byte_to_pointer = (char far*)(address_to);
  479.   dword i;
  480.   for (i = 0; i < bytes; i++){
  481.     swapfile.seekg(offset_from+i);
  482.     byte_to_pointer[i] = swapfile.get();
  483.   }
  484.   if (verbose) cout << "Swapfile move completed.\n";
  485.   return OK;
  486. }
  487.  
  488. XMSerror DashXMM::SF_move(dword bytes, dword offset_to, dword offset_from){
  489.   if (offset_to > offset_from){
  490.     if((offset_from + bytes) > offset_to){
  491.       if (verbose) display_error(INVALID_OVERLAP);
  492.       return INVALID_OVERLAP;
  493.     }
  494.   }
  495.   if (offset_from > offset_to){
  496.     if ((offset_to + bytes) > offset_from){
  497.       if (verbose) display_error(INVALID_OVERLAP);
  498.       return INVALID_OVERLAP;
  499.     }
  500.   }
  501.   dword i;
  502.   char putting;
  503.   for (i = 0; i < bytes; i++){
  504.     swapfile.seekg(offset_from+i);
  505.     putting = swapfile.get();
  506.     swapfile.seekp(offset_to+i);
  507.     swapfile.put(putting);
  508.   }
  509.   if (verbose) cout << "Swapfile move completed.\n";
  510.   return OK;
  511. }
  512.  
  513. XMSerror DashXMM::query(XMSfree& freeXMS){
  514.   XMSerror error;
  515.   if (verbose) cout << "Querying:\n";
  516.   error = query_free_XMS(freeXMS);
  517.   if (error != OK){
  518.     if (verbose) display_error(error);
  519.     if (verbose) cout << "Error, querying Swapfile instead.\n";
  520.     error = query_free_SF(freeXMS);
  521.   }
  522.   if (verbose) cout << "\nLargest: " << freeXMS.largest << ", total: " << freeXMS.total << "\n";
  523.   return error;
  524. }
  525.  
  526. DashXMM::DashXMM(boolean verbosity){ //constructor for NO SWAPFILE REQUESTED!
  527.   using_swapfile = FALSE;
  528.   verbose = verbosity;
  529.   request_swapfile = FALSE;
  530.   if (verbose) cout << "Detecting XMS.\n";
  531.   detect();
  532.   if (verbose) cout << "Initializing XMS.\n";
  533.   initialize();
  534. }
  535.  
  536. DashXMM::DashXMM(boolean verbosity, char* s){  //const. for SWAPFILE REQUEST
  537.   using_swapfile = FALSE;
  538.   verbose = verbosity;
  539.   request_swapfile = TRUE;
  540.   strcpy(swapfile_name, s);
  541.   if (verbose) cout << "Detecting XMS.\n";
  542.   detect();
  543.   if (verbose) cout << "Initializing XMS.\n";
  544.   initialize();
  545. }
  546.  
  547. DashXMM::~DashXMM(void){
  548. }
  549.